﻿using System.Linq;
using Microsoft.Practices.Unity;
using MiniStock.BusinessLogic.QueryLogic.Stock;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System;
using MiniStock.Entities.Common.Query;
using MiniStock.Entities.Stock;
using System.Collections.Generic;
using MiniStock.Database;

namespace MiniStock.BusinessLogic.QueryLogic.Stock.Test
{
    /// <summary>
    ///This is a test class for StockQueryLogicTest and is intended
    ///to contain all StockQueryLogicTest Unit Tests
    ///</summary>
    [TestClass()]
    public class StockQueryLogicTest
    {

        private TestContext testContextInstance;
        public static IUnityContainer RootContainer;

        /// <summary>
        ///Gets or sets the test context which provides
        ///information about and functionality for the current test run.
        ///</summary>
        public TestContext TestContext
        {
            get { return testContextInstance; }
            set { testContextInstance = value; }
        }

        #region Additional test attributes

        // 
        //You can use the following additional attributes as you write your tests:
        //
        //Use ClassInitialize to run code before running the first test in the class

        public static Guid[] CUSTOMER_ID = new[]
                                               {
                                                   Guid.NewGuid(),
                                                   Guid.NewGuid(),
                                               };

        public static Guid[] PRODUCT_ID = new[]
                                               {
                                                   Guid.NewGuid(),
                                                   Guid.NewGuid(),
                                               };

        public static Guid[] ORDER_ID = new[]
                                               {
                                                   Guid.NewGuid(),
                                                   Guid.NewGuid(),
                                               };


        [ClassInitialize()]
        public static void MyClassInitialize(TestContext testContext)
        {
            var context = new EntityDbContext();
            context.Customers.Add(new Customer()
                                      {
                                          Id = CUSTOMER_ID[0],
                                          Name = "Test customer 1",
                                          HQAddress = new Address()
                                                          {
                                                              City = "Testtown",
                                                          },
                                      });
            context.Customers.Add(new Customer()
                                      {
                                          Id = CUSTOMER_ID[1],
                                          Name = "Test customer 2",
                                      });

            context.Products.Add(new Product()
                                     {
                                         Id = PRODUCT_ID[0],
                                         ProductNumber = PRODUCT_ID[0].ToString(),
                                         Name = "Test product 1",
                                         ManufacturerId = CUSTOMER_ID[1],
                                     });
            context.Products.Add(new Product()
                                     {
                                         Id = PRODUCT_ID[1],
                                         ProductNumber = PRODUCT_ID[1].ToString(),
                                         Name = "Test product 2",
                                         ManufacturerId = CUSTOMER_ID[1],
                                     });

            context.Orders.Add(new Order()
                                   {
                                       Id = ORDER_ID[0],
                                       CustomerId = CUSTOMER_ID[0],
                                       OrderReceived = DateTime.Now,
                                       OrderDeadline = DateTime.Today.AddDays(7),
                                       Items = new List<OrderItem>
                                                   {
                                                       new OrderItem()
                                                           {
                                                               Id = Guid.NewGuid(),
                                                               OrderId = ORDER_ID[0],
                                                               ProductId = PRODUCT_ID[0],
                                                               Amount = 10,
                                                           }
                                                   }
                                   });

            context.SaveChanges();
        }

        //
        //Use ClassCleanup to run code after all tests in a class have run
        [ClassCleanup()]
        public static void MyClassCleanup()
        {
            var context = new EntityDbContext();
            foreach (var c in context.OrderItems.Where(i => ORDER_ID.Contains(i.OrderId)))
            {
                context.OrderItems.Remove(c);
            }

            foreach (var c in context.Orders.Where(i => ORDER_ID.Contains(i.Id)))
            {
                context.Orders.Remove(c);
            }
            
            foreach (var c in context.Products.Where(i => PRODUCT_ID.Contains(i.Id)))
            {
                context.Products.Remove(c);
            }

            foreach (var c in context.Customers.Where(i => CUSTOMER_ID.Contains(i.Id)))
            {
                context.Customers.Remove(c);
            }

            context.SaveChanges();
        }

        //
        //Use TestInitialize to run code before running each test
        [TestInitialize()]
        public void MyTestInitialize()
        {
            RootContainer = new UnityContainer();
        }

        //
        //Use TestCleanup to run code after each test has run
        //[TestCleanup()]
        //public void MyTestCleanup()
        //{
        //}
        //

        #endregion


        /// <summary>
        ///A test for ListCustomers
        ///</summary>
        [TestMethod()]
        public void ListCustomersTest()
        {
            StockQueryLogic sut = RootContainer.Resolve<StockQueryLogic>();
            var result = sut.ListCustomers(null, null, null, null);

            Assert.IsNotNull(result);
            Assert.IsTrue(result.Exists(i => i.Id == CUSTOMER_ID[0]));
            Assert.IsTrue(result.Exists(i => i.Id == CUSTOMER_ID[1]));
        }

        /// <summary>
        ///A test for ListCustomers
        ///</summary>
        [TestMethod()]
        public void ListCustomersTest_FilterEmpty()
        {
            StockQueryLogic sut = RootContainer.Resolve<StockQueryLogic>();
            var result = sut.ListCustomers(new List<FilterElement>
                                               {
                                                   FilterElement.Equals("1", "2"),
                                               }
                , null, null, null);

            Assert.IsNotNull(result);
            Assert.AreEqual(0, result.Count);
        }

        /// <summary>
        ///A test for ListCustomers
        ///</summary>
        [TestMethod()]
        public void ListCustomersTest_FilterTest()
        {
            StockQueryLogic sut = RootContainer.Resolve<StockQueryLogic>();
            var result = sut.ListCustomers(
                new List<FilterElement>
                    {
                        FilterElement.Equals("Id", String.Format("'{0}'", CUSTOMER_ID[0])),   
                    }
                , null, null, null);

            Assert.IsNotNull(result);
            Assert.AreEqual(1, result.Count);
            Assert.IsTrue(result.Exists(i => i.Id == CUSTOMER_ID[0]));
        }

        [TestMethod()]
        public void ListProductsTest()
        {
            StockQueryLogic sut = RootContainer.Resolve<StockQueryLogic>();
            var result = sut.ListProducts(null, null, null, null);

            Assert.IsNotNull(result);
            //Assert.IsTrue(result.Exists(i => i.Id == CUSTOMER_ID[0]));
            //Assert.IsTrue(result.Exists(i => i.Id == CUSTOMER_ID[1]));
        }


        [TestMethod()]
        public void ListOrdersTest()
        {
            StockQueryLogic sut = RootContainer.Resolve<StockQueryLogic>();
            var result = sut.ListOrders(null, null, null, null);

            Assert.IsNotNull(result);
            //Assert.IsTrue(result.Exists(i => i.Id == CUSTOMER_ID[0]));
            //Assert.IsTrue(result.Exists(i => i.Id == CUSTOMER_ID[1]));
        }


    }
}
